package com.example.demo.navigation.service;

import com.example.demo.navigation.bean.NavBean;
import com.example.demo.navigation.reposiory.NavRepository;
import com.example.demo.service.BaseService;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Temporal;
import org.springframework.stereotype.Service;

import javax.persistence.Id;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static java.util.stream.Collectors.groupingBy;
import static java.util.stream.Collectors.toList;

@Service
public class NavService extends BaseService<NavBean, NavRepository> {


    private List<NavBean> list;

    public List<NavBean> getList(int type) {
        //xxx 这里是主要考虑到可以缓存资源到lisr里面
//        list = repository.findAll(new Sort(Sort.Direction.DESC, "sort"));
        return repository.findNavBeansByTypeOrderBySort(type,new Sort(Sort.Direction.DESC,"sort"));
    }


    public NavBean addEntity(NavBean navBean) {


        NavBean newparent = null,tempNavBean = null;

        //如果不是一级菜单.则设置他的父级菜单
        if(navBean.getParentId()!=0){
            newparent = repository.findOne((long) navBean.getParentId());
            navBean.setParent(newparent);
        }


        //不是新增,是修改
        if (navBean.getId()!=0){

            if (navBean.getParentId()==navBean.getId()){
                return navBean;
            }

            tempNavBean = repository.findOne(navBean.getId());

            navBean.setChildren(tempNavBean.getChildren());
            int type = repository.findOne(navBean.getId()).getType();
//            tempNavBean.setType(navBean.getType());

            if (navBean.getChildren()!=null) {
                if (type > navBean.getType()) {
                    //说明在升级
                    //性能也存在问题,可以考虑直接使用sql语句批量更新
                    /**
                     *  这里有问题啊..三级应该还看不出来,但是如果是4级的话,可能出现跳级修改的情况,这样的话,-1就是不对的.而且要考虑到子菜单下的子菜单
                     *  3->2 2->1 3->1 三种情况. 其中 3->2 ,3->1 这两种情况不会出现 子菜单变更的情况,
                     *  所以这里主要是处理的是2->1的情况
                     */
                        navBean.getChildren().stream().forEach(b -> {
                            b.setType(b.getType() - 1);
                            repository.save(b);
                        });
                } else if (type < navBean.getType()) {
                    //说明在降级 从一级变到二级 称为降级
                    /**
                     * 1->2,1->3,2->3,其中要考虑,
                     * 2->3这种情况只需要处理原子菜单合并到相同的父级即可,
                     * 1->2 处理把原二级菜单降到三级外,还要考虑原三级菜单的情况,合并到原二级(现三级上)?
                     * 1->3 将原二级,原三级菜单全部合并到现父级菜单上
                     */
                    //已经是最低等级.将原子菜单 进行合并操作
                    if (navBean.getType() == 2) {

                        NavBean finalParent = newparent;
                        if (type == 1) {
                            //2->3这种情况只需要处理原子菜单合并到相同的父级即可
                                navBean.getChildren().stream().forEach(b -> {
                                    b.setType(2);
                                    b.setParent(finalParent);
                                    repository.save(b);
                                });
                        } else {
                            //1->3这种情况
                                navBean.getChildren().stream().forEach(b -> {
                                    if (b.getChildren() != null) {
                                        b.getChildren().stream().forEach(b1 -> {
                                            b1.setParent(finalParent);
                                            repository.save(b1);
                                        });
                                    }
                                    b.setType(2);
                                    b.setParent(finalParent);
                                    repository.save(b);
                                });
                        }
                    } else {
                        //1->2 这种情况
                        //如果navBean 原来是一级菜单(有二级和三级子菜单),现在降到二级,这里的处理方式???
                            NavBean finalNavBean = navBean;
                            navBean.getChildren().stream().forEach(b -> {
                                if (b.getChildren() != null) {
                                    b.getChildren().stream().forEach(b1 -> {
                                        b1.setParent(finalNavBean);
                                        repository.save(b1);
                                    });
                                }
                                b.setType(2);
                                repository.save(b);
                            });
                    }
                }
                //同等级变更不影响
            }
        }
        return repository.save(navBean);
    }
   


//    public List<NavBean> getList(int type, int id) {
//        list = repository.findAll();
//        return list.stream().filter(b -> b.getType() == type && b.getParentId() == id).map(b -> {
//            b.setChildren(list.stream().filter(bb -> bb.getParentId() == b.getId()).collect(Collectors.toList()));
//            return b;
//        }).collect(Collectors.toList());
//    }


    public List<NavBean> getList(int type, int id) {

        //xxx 这里可以优化
        list = repository.findAll();
        return list.stream().filter(b -> b.getType() == type && b.getParentId() == id).map(b -> {
            b.setChildren(list.stream().filter(bb -> bb.getParentId() == b.getId()).collect(Collectors.toList()));
            return b;
        }).collect(Collectors.toList());
    }


    /**
     * 以层级的方式显示出列表
     * @return
     */
    public List<NavBean> getList() {

        List<NavBean> result = new ArrayList<>();
        List<NavBean> list = repository.findAll();
        Map<Integer, List<NavBean>> temp = list.stream().map(b -> {
            switch (b.getType()) {
                case 1:
                    b.setTitle("------" + b.getTitle());
                    break;
                case 2:
                    b.setTitle("-------------" + b.getTitle());
                    break;
                default:
                    break;
            }
            return b;
        }).collect(groupingBy(NavBean::getParentId));

        if (temp.containsKey(0)) {
            temp.get(0).forEach(b -> {
                result.add(b);
                if (temp.containsKey(Integer.valueOf((int) b.getId()))) {
                    temp.get(Integer.valueOf((int) b.getId())).stream().forEach(b1 -> {
                        result.add(b1);
                        if (temp.containsKey(Integer.valueOf((int) b1.getId()))) {
                            result.addAll(temp.get(Integer.valueOf((int) b1.getId())));
                        }
                    });
                }
            });
        }
        return result;

    }
}
